package com.taotao.common.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 常用工具类
 * 
 * @author usky.han
 *
 */
public class Utils {
	private static Logger logger = LoggerFactory.getLogger(Utils.class);

	/**
	 * 全对象非空判断
	 * 
	 * @param obj
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isEmpty(Object obj) {
		try {
			if (obj == null) {
				return true;
			}
			if (obj instanceof Map) {
				if(((Map) obj).isEmpty()||((Map) obj).size()<1){
					return true;
				}
			}
			if (obj instanceof List) {
				if(((List) obj).isEmpty()||((List) obj).size()<1){
					return true;
				}
			}
			if (obj instanceof String) {
				return ((String) obj).trim().isEmpty();
			}
		} catch (Exception e) {
			logger.info("Judgement isEmpty Error " + e);
			return false;
		}

		return false;
	}

	/**
	 * 全类型转Integer,遇到小数位四舍五入
	 * 
	 * @param obj
	 * @return
	 */
	public static Integer valueOfInteger(Object obj) {
		if (obj instanceof String) {
			try {
				return Integer.valueOf((String) obj);
			} catch (NumberFormatException e) {
				return null;
			}
		}
		if (obj instanceof Long) {
			return Integer.valueOf(obj.toString());
		}
		if (obj instanceof Float) {
			return Integer.valueOf((int) Math.rint(((Float) obj).doubleValue()));
		}
		if (obj instanceof Double) {
			return Integer.valueOf((int) Math.rint(((Double) obj).doubleValue()));
		}
		if (obj instanceof BigDecimal) {
			return Integer.valueOf((int) Math.rint(((BigDecimal) obj).doubleValue()));
		}
		if (obj instanceof Integer) {
			return ((Integer) obj).intValue();
		}
		return null;
	}

	/**
	 * 全类型转Long
	 * 
	 * @param obj
	 * @return
	 */
	public static Long valueOfLong(Object obj) {
		if (obj instanceof String) {
			try {
				return Long.valueOf((String) obj);
			} catch (NumberFormatException e) {
				return null;
			}
		}
		if (obj instanceof Long) {
			return ((Long) obj).longValue();
		}
		if (obj instanceof Integer) {
			return Long.valueOf(obj.toString());
		}
		return null;
	}

	/**
	 * 全类型转string
	 * 
	 * @param obj
	 * @return
	 */
	public static String valueOfString(Object obj) {
		return obj == null ? "" : obj.toString();
	}

	/**
	 * Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
	 * 
	 * @param map
	 * @param obj
	 */
	@SuppressWarnings("rawtypes")
	public static void transMap2Bean(final Map<String, Object> map, final Object obj) {
		String key = null;
		Class parameterType = null;
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

			for (PropertyDescriptor property : propertyDescriptors) {
				key = property.getName();
				if (map.containsKey(key)) {
					Object value = map.get(key);
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					parameterType = setter.getParameterTypes()[0];
					if (!isEmpty(value)) {
						if (parameterType.getName().equals("java.lang.Short")) {
							value = new Short(value.toString());
						} else if (parameterType.getName().equals("java.math.BigDecimal")) {
							value = new BigDecimal(value.toString());
						} else if (parameterType.getName().equals("java.util.Date")) {
							value = new Date(Long.valueOf(value.toString()));
						} else if (parameterType.getName().equals("java.lang.Long")) {
							value = Long.valueOf(value.toString());
						} else if (parameterType.getName().equals("java.lang.String")) {
							value = value.toString();
						}
					}
					setter.invoke(obj, value);
				}

			}

		} catch (Exception e) {
			logger.info("transMap2Bean时类型不正确 " + key + "(" + map.get(key) + ") : " + parameterType
					+ "transMap2Bean Error " + e);
		}
	}

	/**
	 * 
	 * @param parameterMap
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> transRequestToMAP(Map<?, ?> parameterMap) {
		// 返回值Map
		Map<String, Object> returnMap = new HashMap<String, Object>();
		Iterator<?> entries = parameterMap.entrySet().iterator();
		Map.Entry<String, String> entry;
		String name = "";
		String value = "";
		while (entries.hasNext()) {
			entry = (Entry<String, String>) entries.next();
			name = (String) entry.getKey();
			Object valueObj = entry.getValue();
			if (null == valueObj) {
				value = "";
			} else if (valueObj instanceof String[]) {
				String[] values = (String[]) valueObj;
				for (int i = 0; i < values.length; i++) {
					value = values[i] + ",";
				}
				value = value.substring(0, value.length() - 1);
			} else {
				value = valueObj.toString();
			}
			returnMap.put(name, value);
		}
		return returnMap;
	}

	/**
	 * Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
	 * 
	 * @param obj
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "deprecation" })
	public static Map<String, Object> transBean2Map(Object obj) {

		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();

				// 过滤class属性
				if (!key.equals("class")) {
					Method setter = property.getReadMethod();
					Class parameterType = setter.getReturnType();
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					if (!isEmpty(value)) {
						if (parameterType.getName().equals("java.lang.Short")) {
							value = Short.valueOf(value.toString());
						} else if (parameterType.getName().equals("java.math.BigDecimal")) {
							value = new BigDecimal(value.toString());
						} else if (parameterType.getName().equals("java.util.Date")) {
							value = DateUtils.fmtDateToYMDHM(new Date(value.toString()));
						}
					}
					map.put(key, value);
				}

			}
		} catch (Exception e) {
			logger.info("transBean2Map Error " + e);
		}

		return map;

	}

	/**
	 * 比较两个BEAN或MAP对象的值是否相等 如果是BEAN与MAP对象比较时MAP中的key值应与BEAN的属性值名称相同且字段数目要一致
	 * 
	 * @param source
	 * @param target
	 * @return
	 */
	public static Map<String, Object> domainEquals(Object source, Object target) {
		if (source == null || target == null) {
			return null;
		}
		Map<String, Object> l_map = new HashMap<String, Object>();
		if (source instanceof Map) {
			mapOfSrc(source, target, l_map);
		} else {
			classOfSrc(source, target, l_map);
		}
		// logger.info("THE EQUALS RESULT IS " + l_map);
		return l_map;
	}

	/**
	 * 源目标为MAP类型时
	 * 
	 * @param source
	 * @param target
	 * @param rv
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static Map<String, Object> mapOfSrc(Object source, Object target, Map<String, Object> l_map) {
		HashMap<String, Object> sourceMap = (HashMap<String, Object>) source;
		for (String key : sourceMap.keySet()) {
			if (target instanceof Map) {
				HashMap<String, Object> tarMap =(HashMap<String, Object>) target;
				if (isEmpty(tarMap.get(key)) && !isEmpty(sourceMap.get(key))) {
					l_map.put(key, null);
					continue;
				}
				if (!isEmpty(tarMap.get(key)) && isEmpty(sourceMap.get(key))) {
					l_map.put(key, tarMap.get(key));
					continue;
				}
				if (isEmpty(tarMap.get(key)) && isEmpty(sourceMap.get(key))) {
					continue;
				}
				if (!sourceMap.get(key).equals(tarMap.get(key))) {
					l_map.put(key, tarMap.get(key));
					continue;
				}
			} else {
				String tarValue = getClassValue(target, key) == null ? "" : getClassValue(target, key).toString();
				if (!tarValue.equals(sourceMap.get(key).toString())) {
					l_map.put(key, tarValue);
					continue;
				}
			}
		}
		return l_map;
	}

	/**
	 * 源目标为非MAP类型时(不推荐使用)
	 * 
	 * @param source
	 * @param target
	 * @param rv
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Map<String, Object> classOfSrc(Object source, Object target, Map<String, Object> l_map) {
		Class<?> srcClass = source.getClass();
		Field[] fields = srcClass.getDeclaredFields();
		for (Field field : fields) {
			String nameKey = field.getName();
			Object o_srcValue = getClassValue(source, nameKey);
			if (target instanceof Map) {
				HashMap<String, String> tarMap = new HashMap<String, String>();
				tarMap = (HashMap) target;
				String srcValue = o_srcValue == null ? "" : o_srcValue.toString();
				if (tarMap.get(nameKey) == null) {
					l_map.put(nameKey, null);
					continue;
				}
				if (!tarMap.get(nameKey).equals(srcValue)) {
					l_map.put(nameKey, tarMap.get(nameKey));
					continue;
				}
			} else {
				Object o_tarValue = getClassValue(target, nameKey);
				String srcValue = o_srcValue == null ? "" : o_srcValue.toString();
				String tarValue = o_tarValue == null ? "" : o_tarValue.toString();
				// 目标对象是空对象时，不作差异比较
				if (!srcValue.equals(tarValue) && o_tarValue != null) {
					l_map.put(nameKey, tarValue);
					continue;
				}
			}
		}
		return l_map;
	}

	/**
	 * 根据字段名称取值
	 * 
	 * @param obj
	 * @param fieldName
	 * @return
	 */
	public static Object getClassValue(Object obj, String fieldName) {
		if (obj == null) {
			return null;
		}
		try {
			Class<?> beanClass = obj.getClass();
			Method[] ms = beanClass.getMethods();
			for (int i = 0; i < ms.length; i++) {
				// 非get方法不取
				if (!ms[i].getName().startsWith("get")) {
					continue;
				}
				Object objValue = null;
				try {
					objValue = ms[i].invoke(obj, new Object[] {});
				} catch (Exception e) {
					logger.info("反射取值出错：" + e.toString());
					continue;
				}
				if (objValue == null) {
					continue;
				}
				if (ms[i].getName().toUpperCase().equals(fieldName.toUpperCase())
						|| ms[i].getName().substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
					return objValue;
				} else if (fieldName.toUpperCase().equals("SID") && (ms[i].getName().toUpperCase().equals("ID")
						|| ms[i].getName().substring(3).toUpperCase().equals("ID"))) {
					return objValue;
				}
			}
		} catch (Exception e) {
			// logger.info("取方法出错！" + e.toString());
		}
		return null;
	}

	public static boolean beanEquals(Object source, Object target) {
		if (source == null && target == null)
			return true;
		if (source != null)
			return source.equals(target);
		if (target != null)
			return target.equals(source);
		return true;
	}

	public static void main(String[] args) {
		String regex = "[^\u4e00-\u9fa5]+";
		boolean matches = Pattern.matches(regex, "adfa/.,");
		System.err.println(matches);
	}
	/**
	 * 
	 * 判断字符串是否为数字
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str){ 
		Pattern pattern = Pattern.compile("[0-9]*"); 
		Matcher isNum = pattern.matcher(str);
		if( !isNum.matches() ){
			return false; 
		} 
		return true; 
	}
}
